home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / cl_tent.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  9KB  |  395 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // cl_tent.c -- client side temporary entities
  21.  
  22. #include "quakedef.h"
  23.  
  24. int            num_temp_entities;
  25. entity_t    cl_temp_entities[MAX_TEMP_ENTITIES];
  26. beam_t        cl_beams[MAX_BEAMS];
  27.  
  28. sfx_t            *cl_sfx_wizhit;
  29. sfx_t            *cl_sfx_knighthit;
  30. sfx_t            *cl_sfx_tink1;
  31. sfx_t            *cl_sfx_ric1;
  32. sfx_t            *cl_sfx_ric2;
  33. sfx_t            *cl_sfx_ric3;
  34. sfx_t            *cl_sfx_r_exp3;
  35. #ifdef QUAKE2
  36. sfx_t            *cl_sfx_imp;
  37. sfx_t            *cl_sfx_rail;
  38. #endif
  39.  
  40. /*
  41. =================
  42. CL_ParseTEnt
  43. =================
  44. */
  45. void CL_InitTEnts (void)
  46. {
  47.     cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav");
  48.     cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav");
  49.     cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav");
  50.     cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav");
  51.     cl_sfx_ric2 = S_PrecacheSound ("weapons/ric2.wav");
  52.     cl_sfx_ric3 = S_PrecacheSound ("weapons/ric3.wav");
  53.     cl_sfx_r_exp3 = S_PrecacheSound ("weapons/r_exp3.wav");
  54. #ifdef QUAKE2
  55.     cl_sfx_imp = S_PrecacheSound ("shambler/sattck1.wav");
  56.     cl_sfx_rail = S_PrecacheSound ("weapons/lstart.wav");
  57. #endif
  58. }
  59.  
  60. /*
  61. =================
  62. CL_ParseBeam
  63. =================
  64. */
  65. void CL_ParseBeam (model_t *m)
  66. {
  67.     int        ent;
  68.     vec3_t    start, end;
  69.     beam_t    *b;
  70.     int        i;
  71.     
  72.     ent = MSG_ReadShort ();
  73.     
  74.     start[0] = MSG_ReadCoord ();
  75.     start[1] = MSG_ReadCoord ();
  76.     start[2] = MSG_ReadCoord ();
  77.     
  78.     end[0] = MSG_ReadCoord ();
  79.     end[1] = MSG_ReadCoord ();
  80.     end[2] = MSG_ReadCoord ();
  81.  
  82. // override any beam with the same entity
  83.     for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
  84.         if (b->entity == ent)
  85.         {
  86.             b->entity = ent;
  87.             b->model = m;
  88.             b->endtime = cl.time + 0.2;
  89.             VectorCopy (start, b->start);
  90.             VectorCopy (end, b->end);
  91.             return;
  92.         }
  93.  
  94. // find a free beam
  95.     for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
  96.     {
  97.         if (!b->model || b->endtime < cl.time)
  98.         {
  99.             b->entity = ent;
  100.             b->model = m;
  101.             b->endtime = cl.time + 0.2;
  102.             VectorCopy (start, b->start);
  103.             VectorCopy (end, b->end);
  104.             return;
  105.         }
  106.     }
  107.     Con_Printf ("beam list overflow!\n");    
  108. }
  109.  
  110. /*
  111. =================
  112. CL_ParseTEnt
  113. =================
  114. */
  115. void CL_ParseTEnt (void)
  116. {
  117.     int        type;
  118.     vec3_t    pos;
  119. #ifdef QUAKE2
  120.     vec3_t    endpos;
  121. #endif
  122.     dlight_t    *dl;
  123.     int        rnd;
  124.     int        colorStart, colorLength;
  125.  
  126.     type = MSG_ReadByte ();
  127.     switch (type)
  128.     {
  129.     case TE_WIZSPIKE:            // spike hitting wall
  130.         pos[0] = MSG_ReadCoord ();
  131.         pos[1] = MSG_ReadCoord ();
  132.         pos[2] = MSG_ReadCoord ();
  133.         R_RunParticleEffect (pos, vec3_origin, 20, 30);
  134.         S_StartSound (-1, 0, cl_sfx_wizhit, pos, 1, 1);
  135.         break;
  136.         
  137.     case TE_KNIGHTSPIKE:            // spike hitting wall
  138.         pos[0] = MSG_ReadCoord ();
  139.         pos[1] = MSG_ReadCoord ();
  140.         pos[2] = MSG_ReadCoord ();
  141.         R_RunParticleEffect (pos, vec3_origin, 226, 20);
  142.         S_StartSound (-1, 0, cl_sfx_knighthit, pos, 1, 1);
  143.         break;
  144.         
  145.     case TE_SPIKE:            // spike hitting wall
  146.         pos[0] = MSG_ReadCoord ();
  147.         pos[1] = MSG_ReadCoord ();
  148.         pos[2] = MSG_ReadCoord ();
  149. #ifdef GLTEST
  150.         Test_Spawn (pos);
  151. #else
  152.         R_RunParticleEffect (pos, vec3_origin, 0, 10);
  153. #endif
  154.         if ( rand() % 5 )
  155.             S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
  156.         else
  157.         {
  158.             rnd = rand() & 3;
  159.             if (rnd == 1)
  160.                 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
  161.             else if (rnd == 2)
  162.                 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
  163.             else
  164.                 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
  165.         }
  166.         break;
  167.     case TE_SUPERSPIKE:            // super spike hitting wall
  168.         pos[0] = MSG_ReadCoord ();
  169.         pos[1] = MSG_ReadCoord ();
  170.         pos[2] = MSG_ReadCoord ();
  171.         R_RunParticleEffect (pos, vec3_origin, 0, 20);
  172.  
  173.         if ( rand() % 5 )
  174.             S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1);
  175.         else
  176.         {
  177.             rnd = rand() & 3;
  178.             if (rnd == 1)
  179.                 S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1);
  180.             else if (rnd == 2)
  181.                 S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1);
  182.             else
  183.                 S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1);
  184.         }
  185.         break;
  186.         
  187.     case TE_GUNSHOT:            // bullet hitting wall
  188.         pos[0] = MSG_ReadCoord ();
  189.         pos[1] = MSG_ReadCoord ();
  190.         pos[2] = MSG_ReadCoord ();
  191.         R_RunParticleEffect (pos, vec3_origin, 0, 20);
  192.         break;
  193.         
  194.     case TE_EXPLOSION:            // rocket explosion
  195.         pos[0] = MSG_ReadCoord ();
  196.         pos[1] = MSG_ReadCoord ();
  197.         pos[2] = MSG_ReadCoord ();
  198.         R_ParticleExplosion (pos);
  199.         dl = CL_AllocDlight (0);
  200.         VectorCopy (pos, dl->origin);
  201.         dl->radius = 350;
  202.         dl->die = cl.time + 0.5;
  203.         dl->decay = 300;
  204.         S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
  205.         break;
  206.         
  207.     case TE_TAREXPLOSION:            // tarbaby explosion
  208.         pos[0] = MSG_ReadCoord ();
  209.         pos[1] = MSG_ReadCoord ();
  210.         pos[2] = MSG_ReadCoord ();
  211.         R_BlobExplosion (pos);
  212.  
  213.         S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
  214.         break;
  215.  
  216.     case TE_LIGHTNING1:                // lightning bolts
  217.         CL_ParseBeam (Mod_ForName("progs/bolt.mdl", true));
  218.         break;
  219.     
  220.     case TE_LIGHTNING2:                // lightning bolts
  221.         CL_ParseBeam (Mod_ForName("progs/bolt2.mdl", true));
  222.         break;
  223.     
  224.     case TE_LIGHTNING3:                // lightning bolts
  225.         CL_ParseBeam (Mod_ForName("progs/bolt3.mdl", true));
  226.         break;
  227.     
  228. // PGM 01/21/97 
  229.     case TE_BEAM:                // grappling hook beam
  230.         CL_ParseBeam (Mod_ForName("progs/beam.mdl", true));
  231.         break;
  232. // PGM 01/21/97
  233.  
  234.     case TE_LAVASPLASH:    
  235.         pos[0] = MSG_ReadCoord ();
  236.         pos[1] = MSG_ReadCoord ();
  237.         pos[2] = MSG_ReadCoord ();
  238.         R_LavaSplash (pos);
  239.         break;
  240.     
  241.     case TE_TELEPORT:
  242.         pos[0] = MSG_ReadCoord ();
  243.         pos[1] = MSG_ReadCoord ();
  244.         pos[2] = MSG_ReadCoord ();
  245.         R_TeleportSplash (pos);
  246.         break;
  247.         
  248.     case TE_EXPLOSION2:                // color mapped explosion
  249.         pos[0] = MSG_ReadCoord ();
  250.         pos[1] = MSG_ReadCoord ();
  251.         pos[2] = MSG_ReadCoord ();
  252.         colorStart = MSG_ReadByte ();
  253.         colorLength = MSG_ReadByte ();
  254.         R_ParticleExplosion2 (pos, colorStart, colorLength);
  255.         dl = CL_AllocDlight (0);
  256.         VectorCopy (pos, dl->origin);
  257.         dl->radius = 350;
  258.         dl->die = cl.time + 0.5;
  259.         dl->decay = 300;
  260.         S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1);
  261.         break;
  262.         
  263. #ifdef QUAKE2
  264.     case TE_IMPLOSION:
  265.         pos[0] = MSG_ReadCoord ();
  266.         pos[1] = MSG_ReadCoord ();
  267.         pos[2] = MSG_ReadCoord ();
  268.         S_StartSound (-1, 0, cl_sfx_imp, pos, 1, 1);
  269.         break;
  270.  
  271.     case TE_RAILTRAIL:
  272.         pos[0] = MSG_ReadCoord ();
  273.         pos[1] = MSG_ReadCoord ();
  274.         pos[2] = MSG_ReadCoord ();
  275.         endpos[0] = MSG_ReadCoord ();
  276.         endpos[1] = MSG_ReadCoord ();
  277.         endpos[2] = MSG_ReadCoord ();
  278.         S_StartSound (-1, 0, cl_sfx_rail, pos, 1, 1);
  279.         S_StartSound (-1, 1, cl_sfx_r_exp3, endpos, 1, 1);
  280.         R_RocketTrail (pos, endpos, 0+128);
  281.         R_ParticleExplosion (endpos);
  282.         dl = CL_AllocDlight (-1);
  283.         VectorCopy (endpos, dl->origin);
  284.         dl->radius = 350;
  285.         dl->die = cl.time + 0.5;
  286.         dl->decay = 300;
  287.         break;
  288. #endif
  289.  
  290.     default:
  291.         Sys_Error ("CL_ParseTEnt: bad type");
  292.     }
  293. }
  294.  
  295.  
  296. /*
  297. =================
  298. CL_NewTempEntity
  299. =================
  300. */
  301. entity_t *CL_NewTempEntity (void)
  302. {
  303.     entity_t    *ent;
  304.  
  305.     if (cl_numvisedicts == MAX_VISEDICTS)
  306.         return NULL;
  307.     if (num_temp_entities == MAX_TEMP_ENTITIES)
  308.         return NULL;
  309.     ent = &cl_temp_entities[num_temp_entities];
  310.     memset (ent, 0, sizeof(*ent));
  311.     num_temp_entities++;
  312.     cl_visedicts[cl_numvisedicts] = ent;
  313.     cl_numvisedicts++;
  314.  
  315.     ent->colormap = vid.colormap;
  316.     return ent;
  317. }
  318.  
  319.  
  320. /*
  321. =================
  322. CL_UpdateTEnts
  323. =================
  324. */
  325. void CL_UpdateTEnts (void)
  326. {
  327.     int            i;
  328.     beam_t        *b;
  329.     vec3_t        dist, org;
  330.     float        d;
  331.     entity_t    *ent;
  332.     float        yaw, pitch;
  333.     float        forward;
  334.  
  335.     num_temp_entities = 0;
  336.  
  337. // update lightning
  338.     for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
  339.     {
  340.         if (!b->model || b->endtime < cl.time)
  341.             continue;
  342.  
  343.     // if coming from the player, update the start position
  344.         if (b->entity == cl.viewentity)
  345.         {
  346.             VectorCopy (cl_entities[cl.viewentity].origin, b->start);
  347.         }
  348.  
  349.     // calculate pitch and yaw
  350.         VectorSubtract (b->end, b->start, dist);
  351.  
  352.         if (dist[1] == 0 && dist[0] == 0)
  353.         {
  354.             yaw = 0;
  355.             if (dist[2] > 0)
  356.                 pitch = 90;
  357.             else
  358.                 pitch = 270;
  359.         }
  360.         else
  361.         {
  362.             yaw = (int) (atan2(dist[1], dist[0]) * 180 / M_PI);
  363.             if (yaw < 0)
  364.                 yaw += 360;
  365.     
  366.             forward = sqrt (dist[0]*dist[0] + dist[1]*dist[1]);
  367.             pitch = (int) (atan2(dist[2], forward) * 180 / M_PI);
  368.             if (pitch < 0)
  369.                 pitch += 360;
  370.         }
  371.  
  372.     // add new entities for the lightning
  373.         VectorCopy (b->start, org);
  374.         d = VectorNormalize(dist);
  375.         while (d > 0)
  376.         {
  377.             ent = CL_NewTempEntity ();
  378.             if (!ent)
  379.                 return;
  380.             VectorCopy (org, ent->origin);
  381.             ent->model = b->model;
  382.             ent->angles[0] = pitch;
  383.             ent->angles[1] = yaw;
  384.             ent->angles[2] = rand()%360;
  385.  
  386.             for (i=0 ; i<3 ; i++)
  387.                 org[i] += dist[i]*30;
  388.             d -= 30;
  389.         }
  390.     }
  391.     
  392. }
  393.  
  394.  
  395.